/**
 * 实现Readonly，接收一个泛型参数，并返回一个完全一样的类型，只是所有属性都会被readonly所修饰
 */
type MyReadonly<T> = {
  readonly [P in keyof T]: T[P];
};

interface Todo {
  title: string;
  description: string;
}

const todoObj: MyReadonly<Todo> = {
  title: "Hey",
  description: "foobar"
};

// console.log(todoObj);
// todoObj.description = "sx";

/**
 * 实现First，他接受一个数组 T 并返回它的第一个元素类型
 */
type First<T extends any[]> = T extends [] ? never : T[0];

type arr1 = ["a", "b", "c"];
type arr2 = [3, 2, 1];

type head1 = First<arr1>;
type head2 = First<arr2>;

/**
 * 实现TupleToObject，传入元组类型，将元组类型转换为对象类型，这个对象类型的键/值都是从元组中遍历出来
 */
type TupleToObject<T extends readonly any[]> = {
  [P in T[number]]: P;
};
const tuple = ["tesla", "model3", "model X", "model Y"] as const;
type result = TupleToObject<typeof tuple>;

/**
 * 创建一个通用的Length，接受一个readonly的数组，返回这个数组的长度。
 */
type Length<T extends readonly unknown[]> = T["length"];
type tesla = [3, 2, 3];

type teslaLengh = Length<tesla>;

/**
 * 从联合类型T中排除U的类型成员，来构造一个新的类型
 */

type MyExclude<T, U> = T extends U ? never : T;

type Result = MyExclude<"a" | "b" | "c", "a">;

enum Status {
  Passed = "Passed",
  InProgress = "InProgress",
  noBegin = "noBegin"
}

// console.log(Status.InProgress);

// any和unknown
function safeParse(s: string): unknown {
  return JSON.parse(s);
}
const obj = safeParse("xx");
